package config

import (
	"encoding/json"
	"strings"

	"github.com/prometheus/alertmanager/mongodb"
	"gopkg.in/mgo.v2/bson"
)

// parseReceiver configure the all receivers of alertmanager.yaml from mongodb receiver collection.
func parseReceiver(alt *mongodb.AlertMongo, conf *Config) (recCfg []*Receiver, err error) {
	notifyT := NotifierConfig{VSendResolved: true}
	notifyF := NotifierConfig{VSendResolved: false}

	receivers, err := alt.QueryAllGroup()
	if err != nil {
		return nil, err
	}

	for _, receiver := range receivers {
		rec := Receiver{Name: receiver.UserGroup}
		var emailCfg EmailConfig
		var internalAPICfg InternalAPIConfig
		var qcloudCfg QcloudVoicepromptConfig
		var phoneStr []string
		var phones string
		var emails []string

		emails = receiver.UserEmails

		for _, email := range emails {
			filter := bson.M{"email": email}
			user, err := alt.QueryOneUser(filter)
			if err != nil {
				continue
			}
			phoneStr = append(phoneStr, user.Phone)
		}
		phones = strings.Join(phoneStr, ",")
		boolFoo := true

		for _, way := range receiver.Notifiers {
			switch way {
			case "email_configs":
				emailCfg = EmailConfig{

					Smarthost:      conf.Global.SMTPSmarthost,
					HTML:           `{{ template "email.default.html" . }}`,
					From:           conf.Global.SMTPFrom,
					Hello:          conf.Global.SMTPHello,
					AuthUsername:   conf.Global.SMTPAuthUsername,
					AuthPassword:   conf.Global.SMTPAuthPassword,
					AuthSecret:     conf.Global.SMTPAuthSecret,
					AuthIdentity:   conf.Global.SMTPAuthIdentity,
					NotifierConfig: notifyF,
					To:             strings.Join(emails, ","),
					Headers:        map[string]string{},
					RequireTLS:     &boolFoo,
				}
				rec.EmailConfigs = []*EmailConfig{&emailCfg}
			case "internal_api_configs":
				internalAPICfg = InternalAPIConfig{
					HTTPConfig:     conf.Global.HTTPConfig,
					APIURL:         conf.Global.InternalAPIURL,
					APIUsername:    conf.Global.InternalAPIUsername,
					MemberID:       conf.Global.InternalAPImemberID,
					SendID:         conf.Global.InternalAPISendID,
					Message:        `{{ template "internalapi.default.message" . }}`,
					NotifierConfig: notifyT,
					To:             phones,
				}
				rec.InternalAPIConfigs = []*InternalAPIConfig{&internalAPICfg}
			case "qcloud_voiceprompt_configs":
				qcloudCfg = QcloudVoicepromptConfig{
					HTTPConfig:     conf.Global.HTTPConfig,
					APIURL:         conf.Global.QcloudAPIVoicepromptURL,
					AppKey:         conf.Global.QcloudAPIAppKey,
					AppID:          conf.Global.QcloudAPIAppid,
					Nationcode:     conf.Global.QcloudAPINationcode,
					Prompttype:     conf.Global.QcloudAPIPrompttype,
					Promptfile:     conf.Global.QcloudAPIPromptfile,
					Playtimes:      conf.Global.QcloudAPIPlaytimes,
					NotifierConfig: notifyT,
					To:             phones,
				}
				rec.QcloudVoicepromptConfigs = []*QcloudVoicepromptConfig{&qcloudCfg}
			}
		}
		recCfg = append(recCfg, &rec)
	}
	return recCfg, nil
}

// parseRoute  configure the all routes of alertmanager.yaml from mongodb route collection.
func parseRoute(alt *mongodb.AlertMongo) (rouCfg []*mongodb.AlertCfgReceiver, err error) {
	routes, err := alt.QueryAllItem()
	if err != nil {
		return nil, err
	}

	for _, route := range routes {
		rou := mongodb.AlertCfgReceiver{
			Receiver: route.UserGroup,
			MatchRE: mongodb.AlertMatchRE{
				Alertname: route.AlertName,
				From:      route.From,
			},
		}
		rouCfg = append(rouCfg, &rou)
	}

	return rouCfg, nil
}

// ParseConfig  configure the routes & receivers of alertmanager.yaml from mongodb alert database
func ParseConfig(alt *mongodb.AlertMongo, conf *Config) error {

	rouCfg, err := parseRoute(alt)
	if err != nil {
		return err
	}

	recCfg, err := parseReceiver(alt, conf)
	if err != nil {
		return err
	}

	rous, err := json.Marshal(rouCfg)
	if err != nil {
		return err
	}

	var rou []*Route
	err = json.Unmarshal(rous, &rou)
	if err != nil {
		return err
	}

	conf.Receivers = recCfg
	conf.Route.Routes = rou

	return nil
}
